-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Local references in Steel.ST #2664
Conversation
Thanks @tahina-pro, this looks great! A few comments:
|
Thank you Aseem for your feedback!
Thank you for your suggestion! Yes, this is exactly the pattern
Yes, that's how I understand effects named
In general, you can nest |
But why not have |
(And for this |
I suspect the frame is not yet determined by the time |
Following our discussion last week, Jonathan told me we shouldn't need |
That sounds good. Here is an untested patch if you want to try without push/pop right away:
|
Thanks Jonathan! I'll merge this PR now and I'll open a follow-up issue on Karamel. |
This PR proposes a lexical Steel.ST combinator to handle references local to a code block, and provides its extraction to C via Karamel: for any initial value
init
and any code blockbody
,Steel.ST.Reference.with_local init body
will "stack-allocate" a local variable, initialize it withinit
, and executebody
with that local variable in scope. Thus, this combinator enables lexical handling of local mutable variables in Steel.ST.Specification
The Steel.ST signature of this combinator:
with_local
is declared in effectSTF
instead ofST
, so that the pre- and post-resources can be properly inferred by the Steel tactic from the caller's context.An example of use in EverParse's ongoing Steel experiment, where I managed to seamlessly replace explicit
alloc
/free
withwith_local
in complex loops going through binary representations of lists (project-everest/everparse@85bd4f0): no additional proof annotation required!Extraction
Following a suggestion by @msprotz, I manage to extract this combinator to Karamel as:
To do that, I had to define 3 local primitives in
Steel.ST.Reference.fst
to be extracted toEPushFrame
,EBufCreate
andEPopFrame
. Since these local primitives are in the.fst
, they are hidden behind the interface and so they will not be used directly by users, only by the implementation ofwith_local
. Thus, I can mark the latterinline_for_extraction
and benefit from cross-module inlining.Thus,
with_local init body
is extracted to C as:In the EverParse example mentioned above, here is the diff to the corresponding extracted code, where arrays allocated with
KRML_HOST_CALLOC
are replaced with local variables: tahina-pro/quackyducky@7552898(FWIW, this PR also provides a similar combinator for ghost local variables,
Steel.ST.GhostReference.with_local
, but this one does not need any additional primitives for extraction.)For now this PR handles local references only: no arrays yet. We would extend to arrays only once the design of this PR is validated and it is merged.